package com.basker.pisces.tools.web;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.basker.pisces.cache.ICache;
import com.basker.pisces.cache.ICacheManager;
import com.basker.pisces.service.annotation.IgnoreLoginContext;
import com.basker.pisces.service.dto.IServiceResult;
import com.basker.pisces.service.dto.ServiceResultFactory;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@RestController
@RequestMapping("/t/cache/manage")
public class CacheManageController implements ApplicationContextAware {
    public static final String DEFAULT_CACHE_MANAGER = "defaultCacheManager";
    public static final String DEFAULT_DATACONTRACT_CACHE_MANAGER = "defaultDataContractCacheManager";

    private ApplicationContext applicationContext;

    /**
     * 自定义缓存清除,必须传入cacheName
     *
     * @param cacheRequest
     * @return
     */
    @PostMapping("/clear")
    @IgnoreLoginContext
    public IServiceResult<Void> clear(@RequestBody CacheRequest cacheRequest) {
        ICacheManager cacheManager = applicationContext.getBean(DEFAULT_CACHE_MANAGER, ICacheManager.class);
        String cacheName = cacheRequest != null ? cacheRequest.getCacheName() : null;
        Assert.notNull(cacheName, "parameter 'cacheName' is required is required!");

        ICache<?, ?> cache = cacheManager.getCache(cacheName);
        cache.clear();

        return ServiceResultFactory.ok(cacheRequest + " is clear");
    }

    /**
     * 持久层框架缓存清除,传入cacheName(ORM类的完整类名)，清除指定缓存，否则清除所有持久层框架的缓存
     *
     * @param cacheRequest
     * @return
     */
    @PostMapping("/datacontract/clear")
    @IgnoreLoginContext
    public IServiceResult<Void> datacontractClear(@RequestBody @Nullable CacheRequest cacheRequest) {
        ICacheManager cacheManager = applicationContext.getBean(DEFAULT_DATACONTRACT_CACHE_MANAGER,
                ICacheManager.class);
        String cacheName = cacheRequest != null ? cacheRequest.getCacheName() : null;

        if (StringUtils.isEmpty(cacheName)) {
            cacheManager.clear();

            return ServiceResultFactory.ok("All DataContract Cache is clear");
        } else {
            ICache<?, ?> cache = cacheManager.getCache(cacheName);
            cache.clear();

            return ServiceResultFactory.ok(cacheRequest + " is clear");
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

    }

    @Getter
    @Setter
    @ToString
    public static class CacheRequest {
        private String cacheName;
    }
}
